package com.videoweb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.videoweb.entity.Role;
import com.videoweb.entity.RoleMenu;
import com.videoweb.entity.UserRole;
import com.videoweb.mapper.RoleMapper;
import com.videoweb.service.IRoleMenuService;
import com.videoweb.service.IRoleService;
import com.videoweb.service.IUserRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.videoweb.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 *  角色服务实现类
 * </p>
 *
 * @author lmr
 * @since 2025-05-17
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private IRoleMenuService roleMenuService;

    @Autowired
    private IUserRoleService userRoleService;

    @Override
    public List<Role> selectRoleList(Role role) {
        return roleMapper.selectRoleList(role);
    }

    @Override
    public IPage<Role> selectRolePage(Page<Role> page, Role role) {
        return roleMapper.selectRolePage(page, role);
    }

    @Override
    public Set<String> selectRolePermissionByUserId(Long userId) {

        List<Role> perms = roleMapper.selectRolePermissionByUserId(userId);
        Set<String> permsSet = new HashSet<>();
        for (Role perm : perms)
        {
            if (StringUtils.isNotNull(perm))
            {
                permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
            }
        }

        return permsSet;
    }

    @Override
    public List<Role> selectRolesByUserId(Long userId) {
        return roleMapper.selectRolesByUserId(userId);
    }

    @Override
    public List<Role> selectRoleAll() {
        return list();
    }

    @Override
    public Role selectRoleById(Long roleId) {
        return roleMapper.selectRoleById(roleId);
    }

    @Override
    public boolean checkRoleNameUnique(Role role) {
        Long roleId = StringUtils.isNull(role.getId()) ? -1L : role.getId();
        Role info = roleMapper.checkRoleNameUnique(role.getName(), roleId);
        if (StringUtils.isNotNull(info) && info.getId().longValue() != roleId.longValue()) {
            return false;
        }
        return true;
    }

    @Override
    public boolean checkRoleKeyUnique(Role role) {
        Long roleId = StringUtils.isNull(role.getId()) ? -1L : role.getId();
        Role info = roleMapper.checkRoleKeyUnique(role.getRoleKey(), roleId);
        if (StringUtils.isNotNull(info) && info.getId().longValue() != roleId.longValue()) {
            return false;
        }
        return true;
    }

    @Override
    public void checkRoleAllowed(Role role) {
        if (StringUtils.isNotNull(role.getId()) && role.getId() == 1L) {
            throw new RuntimeException("不允许操作超级管理员角色");
        }
    }

    @Override
    public int countUserRoleByRoleId(Long roleId) {
        return roleMapper.countUserRoleByRoleId(roleId);
    }

    @Override
    @Transactional
    public boolean insertRole(Role role) {
        // 新增角色信息
        boolean result = save(role);
        if (result && StringUtils.isNotEmpty(role.getMenuIds())) {
            // 新增用户与角色管理
            insertRoleMenu(role);
        }
        return result;
    }

    @Override
    @Transactional
    public boolean updateRole(Role role) {
        // 修改角色信息
        boolean result = updateById(role);
        if (result && StringUtils.isNotEmpty(role.getMenuIds())) {
            // 修改用户与角色管理
            roleMenuService.remove(new LambdaQueryWrapper<RoleMenu>()
                    .eq(RoleMenu::getRoleId, role.getId()));
            insertRoleMenu(role);
        }
        return result;
    }

    @Override
    public boolean updateRoleStatus(Role role) {
        return updateById(role);
    }

    @Override
    public boolean authDataScope(Role role) {
        return updateById(role);
    }

    @Override
    @Transactional
    public boolean deleteRoleById(Long roleId) {
        // 删除角色与菜单关联
        roleMenuService.remove(new LambdaQueryWrapper<RoleMenu>()
                .eq(RoleMenu::getRoleId, roleId));
        // 删除角色与用户关联
        userRoleService.remove(new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getRoleId, roleId));
        return removeById(roleId);
    }

    @Override
    @Transactional
    public boolean deleteRoleByIds(Long[] roleIds) {
        for (Long roleId : roleIds) {
            checkRoleAllowed(new Role().setId(roleId));
            Role role = selectRoleById(roleId);
            if (countUserRoleByRoleId(roleId) > 0) {
                throw new RuntimeException(String.format("%1$s已分配,不能删除", role.getName()));
            }
        }
        // 删除角色与菜单关联
        roleMenuService.remove(new LambdaQueryWrapper<RoleMenu>()
                .in(RoleMenu::getRoleId, Arrays.asList(roleIds)));
        // 删除角色与用户关联
        userRoleService.remove(new LambdaQueryWrapper<UserRole>()
                .in(UserRole::getRoleId, Arrays.asList(roleIds)));
        return removeByIds(Arrays.asList(roleIds));
    }

    /**
     * 新增角色菜单信息
     * @param role 角色对象
     */
    public void insertRoleMenu(Role role) {
        List<RoleMenu> list = role.getMenuIds().stream().map(menuId -> {
            RoleMenu rm = new RoleMenu();
            rm.setRoleId(role.getId());
            rm.setMenuId(menuId);
            return rm;
        }).toList();
        roleMenuService.saveBatch(list);
    }
}
